// 官方解-自动机
class Automation {
    constructor(s) {
        // 初始化状态为start，结果为0，符号位正
        this.state = "start"
        this.answer = 0
        this.sign = 1
        this.str = s

        // 执行阶段和状态的对照
        // 执行阶段为开始时，如果输入为空格、符号、数字或其他对应的状态
        // 执行阶段为已确认符号时，如果输入为空格、符号、数字或其他对应的状态
        // 执行阶段为生成数值时，如果输入为空格、符号、数字或其他对应的状态
        // 执行阶段为其他时，如果输入为空格、符号、数字或其他对应的状态
        this.stateMap = new Map([
            ['start', ['start', 'signed', 'in_number', 'end']],
            ['signed', ['end', 'end', 'in_number', 'end']],
            ['in_number', ['end', 'end', 'in_number', 'end']],
            ['end', ['end', 'end', 'end', 'end']]
        ])
    }

    getIndex(char) {
        // 0,1,2,3对应stateMap中状态的索引
        if (char === ' ') return 0
        if (char === '-' || char === '+') return 1
        if (char >= '0' && char <= '9') return 2
        return 3
    }

    calAnswer() {
        for (let char of this.str) {
            this.state = this.stateMap.get(this.state)[this.getIndex(char)]

            if (this.state === 'end') {
                break
            } else if (this.state === 'in_number') {
                this.answer = this.answer * 10 + char * this.sign

                this.answer = this.sign === 1 ? Math.min(this.answer, -(1 << 31) - 1) : Math.max(this.answer, (1 << 31))
            } else if (this.state === 'signed') {
                this.sign = char === '+' ? 1 : -1
            }
        }
    }
}

/**
 * @param {string} s
 * @return {number}
 */
function myAtoi(s) {
    let automation = new Automation(s)
    automation.calAnswer()
    return automation.answer
};



// 直接解
function myAtoi(s) {
    let res, temp;
    let sign = 1
    for (let i = 0; i < s.length; i++) {
        const item = s[i];
        if (res === undefined && item === " ") continue
        if (res === undefined && (item === "-" || item === "+")) {
            res = temp = 0
            sign = item === "-" ? -1 : 1
            continue
        }
        if (item >= "0" && item <= "9") {
            temp = ~~res * 10 + item * sign
        } else {
            break
        }
        if (temp < (1 << 31)) {
            res = (1 << 31)
            break
        }
        if (temp > (-(1 << 31) - 1)) {
            res = (-(1 << 31) - 1)
            break
        }
        res = temp
    }
    return res || 0
};

console.log(myAtoi("   +0 123"))